use chrono::{Datelike, Months, NaiveDate};
use comp::comp_asse_proc;
use indi::indi_asse_proc;

use crate::{base::{create_tmp_table, exec_sqls, get_config, get_sys_date, reload_dicts, SqlList}, big_table::asse_ftp_back};
mod comp;
mod indi;

pub async fn asse_proc(back_date: &NaiveDate) -> anyhow::Result<()> {
    let asse_dicts= &get_config().asse_dicts;
    reload_dicts(asse_dicts).await?;
    let mut sdate = NaiveDate::from_ymd_opt(back_date.year(), back_date.month() + 1, 1).unwrap();
    sdate = sdate - chrono::Duration::days(1);
    let end_date = get_sys_date(crate::base::SourceType::EDW).await?;
    let start_date=sdate.clone();
    let sl = SqlList::Path("asse_before".to_owned());
    create_tmp_table("T_COMP_FACT_ASSE", "TMP_COMP_FACT_ASSE").await?;
    create_tmp_table("T_INDI_SAVE_FACT_ASSE", "TMP_INDI_SAVE_FACT_ASSE").await?;
    create_tmp_table("T_INDI_LOAN_FACT_ASSE", "TMP_INDI_LOAN_FACT_ASSE").await?;
    exec_sqls(&sl, &[], &[]).await.or_else(|err| {
        Err(anyhow::anyhow!(
            "生成考核结果时执行asse_before.sql失败:{}",
            err
        ))
    })?;
    loop {
        let sdate_str = sdate.format("%Y-%m-%d").to_string();
        comp_asse_proc(&sdate)
            .await
            .or_else(|err| Err(anyhow::anyhow!("生成{sdate_str}对公考核结果时失败:{}", err)))?;
        indi_asse_proc(&sdate)
            .await
            .or_else(|err| Err(anyhow::anyhow!("生成{sdate_str}零售考核结果时失败:{}", err)))?;
        if sdate >= end_date {
            break;
        }
        sdate = sdate.checked_add_months(Months::new(1)).unwrap();
        if sdate > end_date {
            sdate = end_date
        }
    }
    let sl = SqlList::Path("asse_after".to_owned());
    let sdate_str = sdate.format("%Y-%m-%d").to_string();
    exec_sqls(&sl, &["{date}"], &[&sdate_str]).await.or_else(|err| {
        Err(anyhow::anyhow!(
            "生成考核结果时执行asse_after.sql失败:{}",
            err
        ))
    })?;
    asse_ftp_back(&start_date,&end_date).await?;
    Ok(())
}
